import io
import re
import shutil
import subprocess
import tempfile
import threading
import time
from docxtpl import DocxTemplate, InlineImage
from docx.shared import Mm
import os
import uuid
from django.conf import settings
from django.http import JsonResponse
from django.shortcuts import render
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_http_methods
from openpyxl import load_workbook
import qrcode
from doc_service.models import RepModel, Report
from doc_service.utils import fake_sign, merge_pdfs, num_to_rmb
from reportservice.helpers import ApiResponse, create_directories_if_not_exist
import json
from datetime import datetime, timezone, timedelta
from oss_service.views import bucket,digital_bucket
from yida_app_service.chengxiang.digital_sign_view import create_digital_sign_order_thread
from yida_app_service.chengxiang.test import record_log, start_backup_task_test
from yida_app_service.chengxiang.xm_cloud_config import XmCloudClient
from yida_app_service.chengxiang.xm_digital_sign_config import XmDigitalSignClient
from yida_app_service.models import DocxRenderRecord
from yida_app_service.utils.common_utils import date_format
from .yida_config import YidaClient
import logging
import pandas as pd
import openpyxl
from openpyxl.styles import Border, Side
from openpyxl.utils.cell import range_boundaries
from openpyxl.utils import coordinate_to_tuple
import re
from concurrent.futures import ThreadPoolExecutor, as_completed
from queue import Queue
from threading import Thread
import requests
from django.core.cache import cache
import fitz
from fitz import FileDataError
xm_digital_sign_client = XmDigitalSignClient()
yida_client = YidaClient()
xm_client = XmCloudClient()

logger = logging.getLogger(__name__)
admin_user_id = "301546025724261514"
report_form_uuid = "FORM-5E859C69D49F452694E420EF7A162B4371MF"
finicial_form_uuid = "FORM-BAFAA96000BA4C44A0C8F3256EB00407RP4T"
# tmp_path = os.path.join(settings.BASE_DIR, r'data/xiaming_tmp/chengxiang')
tmp_path = os.path.join(settings.BASE_DIR, r'yida_app_service/chengxiang/resorce')
# yida_app_service/chengxiang/resorce
thin_border = Border(left=Side(style='thin'), 
                     right=Side(style='thin'), 
                     top=Side(style='thin'), 
                     bottom=Side(style='thin'))
count = 0


# 打印所有的财务清单
@csrf_exempt
@require_http_methods(["POST"])
def print_by_xlsx(request,sheet_uuid):
    datasource = json.loads(request.body.decode())
    search = datasource.get('search',{})
    # 启动后台线程来执行耗时任务
    thread = Thread(target=print_by_xlsx_background_task, args=(datasource, sheet_uuid))
    thread.start()
    # 立即返回响应
    return ApiResponse.success("打印中，请等待，成功后请在钉钉中查找打印结果")

# 打印所有数据的逻辑代码
def print_by_xlsx_background_task(datasource,sheet_uuid):
    # print('datasource',datasource)
    current_page = 1
    page_size = 99
    all_report_data = []  # 用于存储所有页面的数据
    while True:
        report_data = yida_client.get_form_data_by_search_field(
            report_form_uuid,
            admin_user_id,
            datasource["search"],
            # {
            # "dateField_lp92f309": datasource["record_date"],
            # "textField_lqetx3jq": datasource["salesman"],
            # },
            current_page=current_page,
            page_size=page_size
        )
        print(report_data)
        # 将获取的数据添加到all_report_data列表中
        all_report_data.extend(report_data)
        # 打印获取的数据长度
        print(len(report_data))
        # 检查是否还有更多的数据（即本次获取的数据长度是否小于page_size）
        if len(report_data) < page_size:
            break  # 如果没有更多数据，退出循环
        current_page += 1  # 准备获取下一页的数据
    # 打印总数据长度
    print(f"Total data length: {len(all_report_data)}")
    print_by_xlsx_utils(all_report_data,datasource,sheet_uuid)


# 打印指定的财务清单
@csrf_exempt
@require_http_methods(["POST"])
def print_Appoint_by_xlsx(request,sheet_uuid):
    datasource = json.loads(request.body.decode())
    # 启动后台线程来执行耗时任务
    thread = Thread(target=print_Appoint_by_xlsx_background_task, args=(datasource, sheet_uuid))
    thread.start()
    # 立即返回响应
    return ApiResponse.success("打印中，请等待，成功后请在钉钉中查找打印结果")

# 打印指定清单的逻辑代码
def print_Appoint_by_xlsx_background_task(datasource,sheet_uuid):
    # 打印总数据长度
    all_report_data = yida_client.get_form_items_by_id_list(
        report_form_uuid,
        datasource['formInstanceIdList'],
        admin_user_id
    )
    print(all_report_data[0])
    print_by_xlsx_utils(all_report_data,datasource,sheet_uuid)




# 导出全部财务数据
@csrf_exempt
@require_http_methods(["POST"])
def print_financial_xlsx(request):
    # 解析JSON数据
    try:
        data = json.loads(request.body)
        search = data.get('search',{})
        # 启动后台线程来执行耗时任务
        thread = Thread(target=print_financial_xlsx_background_task, args=(search,))
        thread.start()
        # 立即返回响应
        # "导出中，请等待，成功后请在钉钉中查找打印结果"
        return ApiResponse.success("导出中，请等待，成功后请在钉钉中查找打印结果")
    except json.JSONDecodeError:
        return JsonResponse({'error': '无效的JSON'}, status=400)

def print_financial_xlsx_background_task(search):
    all_report_data,total = yida_client.get_all_form_data_by_search_field(
        report_form_uuid,
        admin_user_id,
        search,
    )
    print_financial_xlsx_utils(all_report_data)
    

# 导出指定财务数据
@csrf_exempt
@require_http_methods(["POST"])
def print_Appoint_financial_xlsx(request):
    # 解析JSON数据
    try:
        data = json.loads(request.body)
        # search = data.get('search',{})
        formInstanceIdList = data.get('formInstanceIdList',[])
        print("formInstanceIdList",formInstanceIdList)
        # return '1'
        # 启动后台线程来执行耗时任务
        thread = Thread(target=print_Appoint_financial_xlsx_background_task, args=(formInstanceIdList,))
        thread.start()
        # 立即返回响应
        # "导出中，请等待，成功后请在钉钉中查找打印结果"
        return ApiResponse.success("导出中，请等待，成功后请在钉钉中查找打印结果")
    except json.JSONDecodeError:
        return JsonResponse({'error': '无效的JSON'}, status=400)

def print_Appoint_financial_xlsx_background_task(formInstanceIdList):
    all_report_data = yida_client.get_form_items_by_id_list(
        report_form_uuid,
        formInstanceIdList,
        admin_user_id
    )
    print_financial_xlsx_utils(all_report_data)
    

# 
@csrf_exempt
@require_http_methods(["POST"])
def saving_signature_photos(request):
    try:
        data = json.loads(request.body)
        user_dingtalk_id = data.get('user_dingtalk_id','')
        # print(user_dingtalk_id)
        all_report_data = yida_client.get_form_data_by_search_field(
            "FORM-861F9E6F4AAE4D73A255247BF7991765XAKG",
            admin_user_id,
            {
                "textField_lp0zbal4": user_dingtalk_id
            }
        )
        url = 'https://api.zjcxjc.cn/api/v1/digital-sign/get-personinfo-by-dingtalk-id'
        query_params = {
            'dingtalkUserId': user_dingtalk_id
        }
        # 发送GET请求并传递参数
        response = requests.get(url, params=query_params)
        if response.status_code == 200:
            # 解析响应内容
            data = response.json()
            key = f"{data['data']['personInformationPath']}sealfile.png"
        response = requests.get(all_report_data[0].form_data['digitalSignatureField_lp0tv65b'])
        if response.status_code == 200:
            # print(response.content)
            print(key)
            digital_bucket.put_object(key,response.content)
            sign_url = digital_bucket.sign_url("GET",key,600)
            return ApiResponse.success(sign_url)
    except json.JSONDecodeError:
        return JsonResponse({'error': '无效的JSON'}, status=400)
    

# --------------------------------------
# 配置函数-公共

# 打印清单的公共代码
# 传入all_report_data：获取到的项目信息流程的数据
# 调用财务流程表获取数据并且将数据写入到oss中并且返回url链接并创建新数据到打印表
def print_by_xlsx_utils(all_report_data,datasource,sheet_uuid):
    table_data = []
    for index,item in enumerate(all_report_data):
        text1 = item.form_data['textField_lp93kxwo']
        num1 = float(re.search(r'\d+(\.\d+)?', text1).group()) if re.search(r'\d+(\.\d+)?', text1) else 0
        text2 = item.form_data['textField_lp93kxwq']
        num2 = float(re.search(r'\d+(\.\d+)?', text2).group()) if re.search(r'\d+(\.\d+)?', text2) else 0
        timestamp_ms = item.form_data['dateField_lp92f309']
        # 将毫秒级时间戳转换为秒级时间戳
        timestamp_s = timestamp_ms / 1000
        # 使用 datetime 从秒级时间戳创建 datetime 对象
        dt_object = datetime.fromtimestamp(timestamp_s)
        # 将 datetime 对象格式化为字符串
        formatted_date = dt_object.strftime('%Y-%m-%d')
        table_data_item = [
            index+1,
            formatted_date,
            item.form_data['textField_lp93kxup'],
            item.form_data['textField_lphpacz4'],
            item.form_data['textField_lphpacz0'],
            num1,
            num2
        ]
        # print(table_data_item)
        table_data.append(table_data_item)
    with ThreadPoolExecutor(max_workers=2) as executor:
        future_to_item = {executor.submit(get_financial_data, item): item for item in table_data}
        for future in as_completed(future_to_item):
            try:
                # 确保任务完成，捕获并处理异常
                result = future.result()
            except Exception as e:
                print(f"Task generated an exception: {e}")
        print(table_data)
        table_data_num =  f'共{len(table_data)}单'
        # return ApiResponse.success(len(all_report_data))
        amount_data = sum([item[-1] for item in table_data if item])
        amount_zh_data = num_to_rmb(amount_data)
        df = pd.DataFrame(table_data)
        logger.info(sheet_uuid)
        sheet_path = os.path.join(tmp_path, f"{sheet_uuid}.xlsx")
        sheet_name = 'Sheet1'
        book = load_workbook(sheet_path)
        sheet = book[sheet_name]
        salesman = datasource["salesman"]
        insert_value_to_cell(sheet,"C2",salesman)
        start_date = datasource["record_date"][0]
        end_date = datasource["record_date"][1]
        start_date = datetime.fromtimestamp(start_date/1000).strftime('%Y年%m月%d')
        end_date = datetime.fromtimestamp(end_date/1000).strftime('%Y年%m月%d')
        insert_value_to_cell(sheet,"E2",f"{start_date} 至 {end_date}")
        now_date = datetime.now().strftime('%Y年%m月%d')
        insert_value_to_cell(sheet,"H2",now_date)
        insert_value_to_cell(sheet,"G8",amount_data)
        insert_value_to_cell(sheet,"D8",amount_zh_data)
        insert_value_to_cell(sheet,"A8",table_data_num)
        # 在插入行之前，记录所有合并单元格的范围
        row_heights = {row: sheet.row_dimensions[row].height for row in range(1, sheet.max_row + 1)}
        merged_cells_ranges = [str(merged_cell) for merged_cell in sheet.merged_cells.ranges]
        # 删除原合并单元格设置以避免插入时出现错误
        for merged_cell in merged_cells_ranges:
            sheet.unmerge_cells(merged_cell)
            
        df_rows = df.shape[0]
        startrow = 5
        sheet.insert_rows(startrow, df_rows)
        for i, row in df.iterrows():
            for j, value in enumerate(row):
                cell = sheet.cell(row=startrow + i, column=j + 1, value=value)
                cell.border = thin_border

        # 重新设置行高
        for row, height in row_heights.items():
            if row >= 4:  # 调整新增行之后的行高
                sheet.row_dimensions[row + df_rows].height = height
            else:  # 保留新增行之前的行高
                sheet.row_dimensions[row].height = height
        # 重新合并单元格
        for merged_cell in merged_cells_ranges:
            min_col, min_row, max_col, max_row = range_boundaries(merged_cell)
            # 调整行号以反映新插入的行
            if min_row >= 4:
                min_row += df_rows
                max_row += df_rows
            new_range = f"{openpyxl.utils.get_column_letter(min_col)}{min_row}:{openpyxl.utils.get_column_letter(max_col)}{max_row}"
            sheet.merge_cells(new_range)
        save_sheet_path = os.path.join(tmp_path, f"{sheet_uuid}_print.xlsx")
        # 保存更改
        book.save(save_sheet_path)
        key = f"file_tmp/{datetime.now().strftime('%Y%m')}/{uuid.uuid4()}.xlsx"
        bucket.put_object_from_file(key,save_sheet_path)
        sign_url = bucket.sign_url("GET",key,600)
        # return ApiResponse.success(sign_url)
        yida_client.create_form_data(
            "FORM-C72E2260C4154109B9821B99E3430584V2WE",
            admin_user_id,
            {"textField_lurphsap": sign_url},
        )

# 获取财务数据并格式化 - 打印清单
def get_financial_data(item):
    financial_data = yida_client.get_form_data_by_search_field(
        "FORM-BAFAA96000BA4C44A0C8F3256EB00407RP4T",
        admin_user_id,
        {"textField_ltmbnezf": item[2]},
        current_page=1, page_size=1
    )
    # print('--report>>>>>>>',financial_data[0].form_data['numberField_lv0lyit9'])
    item.extend([
        float(financial_data[0].form_data['numberField_lv0lyit9_value']) if financial_data[0].form_data['numberField_lv0lyit9_value'] else 0,
        float(financial_data[0].form_data['numberField_lv0lyita_value']) if financial_data[0].form_data['numberField_lv0lyita_value'] else 0,
        float(financial_data[0].form_data['numberField_lv0lyitb_value']) if financial_data[0].form_data['numberField_lv0lyitb_value'] else 0,
        float(financial_data[0].form_data['numberField_lv0lyitc_value']) if financial_data[0].form_data['numberField_lv0lyitc_value'] else 0,
        float(financial_data[0].form_data['numberField_lv0lyite_value']) if financial_data[0].form_data['numberField_lv0lyite_value'] else 0,
        float(financial_data[0].form_data['numberField_lv0lyitf_value']) if financial_data[0].form_data['numberField_lv0lyitf_value'] else 0,
        float(financial_data[0].form_data['numberField_lv0lyith_value']) if financial_data[0].form_data['numberField_lv0lyith_value'] else 0,
        float(financial_data[0].form_data['numberField_lv0lyiti_value']) if financial_data[0].form_data['numberField_lv0lyiti_value'] else 0,
    ])
    if not item:
        print(f">>>>>>>>{item[2]}")
    return item  # 返回更新后的item


def insert_value_to_cell(sheet, cell_coordinate, value):
    """在指定单元格内插入数据"""
    # 将单元格坐标（如'E2'）转换为行列数（如(2, 5)）
    row, column = coordinate_to_tuple(cell_coordinate)
    sheet.cell(row=row, column=column, value=value)


# 导出数据的公共代码
# 传入all_report_data：获取到的项目信息流程的数据
# 调用财务流程表获取数据并且将数据写入到oss中并且返回url链接并创建新数据到打印表
def print_financial_xlsx_utils(all_report_data):
    data_to_write = []
    headers = [
        '登记日期', '归属地', '县级归属地', '委托方', '工程名称', '报告编号',
        '总面积', '单价', '总检测费', '公司收款', '业务员收款', '管理费',
        '税额', '其他款项', '其他税额', '社保金额', '结算金额', '收款状态'
    ]
    # print(report_code_list)
    # 使用 Queue 来安全地从线程收集数据
    results_queue = Queue()
    if(len(all_report_data)> 0):
        with ThreadPoolExecutor(max_workers=1) as executor:
            # 提交所有报告数据到线程池，开始处理
            futures = [executor.submit(process_report_data_wrapper, report_data, results_queue) for report_data in all_report_data]
            # 等待所有线程处理完成
            for future in as_completed(futures):
                try:
                    result = future.result()
                except Exception as exc:
                    print(f'处理报告数据时发生错误: {exc}')
        data_to_write = list(results_queue.queue)
        print('data_to_write',data_to_write)
        df = pd.DataFrame(data_to_write, columns=headers)
        # 写入Excel文件
        output = io.BytesIO()
        df.to_excel(output, index=False, engine='openpyxl')
        output.seek(0)
        print(f'数据已写入缓存')
        # 上传oss
        current_date = datetime.now()
        formatted_date = current_date.strftime('%Y%m')
        file_name = f'financial_report-{datetime.now().strftime("%Y%m%d%H%M%S")}.xlsx'
        key = f'file_tmp/{formatted_date}/{file_name}'
        bucket.put_object(key,output.getvalue())
        sign_url = bucket.sign_url("GET",key,24*3600)
        # return ApiResponse.success(sign_url)
        yida_client.create_form_data(
            "FORM-C72E2260C4154109B9821B99E3430584V2WE",
            admin_user_id,
            {"textField_lurphsap": sign_url},
        )
    else:
        return JsonResponse({'error': '无参数'}, status=400)

def process_report_data_wrapper(report_data, results_queue):
    try:
        result = process_report_data(report_data, results_queue)
        return result
    except Exception as exc:
        print(f"处理报告数据时发生错误: {exc}")
        return None
# 获取财务数据并格式化 - 导出数据
def process_report_data(report_data,results_queue):
    report_form_data = report_data.form_data
    cache_key = f"chengxiang:form_data:{finicial_form_uuid}:{report_form_data['textField_lp93kxup']}"
    financial_data_res_cache = cache.get(cache_key)
    if financial_data_res_cache:
        print("从缓存读取")
        financial_data = json.loads(financial_data_res_cache)
        process_status = financial_data.get("process_status")
        if not process_status:
            cache.delete(cache_key)
            return process_report_data(report_data,results_queue)
        if process_status =='待预算':
            collection_status = '未收款'
        elif process_status =='结算':
            collection_status = '部分已收'
        elif process_status =='结清':
            collection_status = '已收'
    else:
        print("从表单读取")
        financial_data_res = yida_client.get_form_data_by_search_field(
            "FORM-BAFAA96000BA4C44A0C8F3256EB00407RP4T",
            admin_user_id,
            [
                {
                "type": "TEXT",
                "operator": "eq",
                "componentName": "TextField",
                "key": "textField_ltmbnezf",
                "value": report_form_data['textField_lp93kxup']
                }
            ]
            )
        if not financial_data_res:
            financial_data = None
        else:
            financial_data = financial_data_res[0]
            cache_data = {
                "form_data": financial_data.form_data,
                "form_instance_id":financial_data.form_instance_id,
                "process_status":'待预算',
            }
            financial_InstanceId = financial_data.form_instance_id
            print('financial_InstanceId',financial_InstanceId)
            # 财务表单————审批状态
            if not financial_InstanceId:
                results_queue.put({
                    '报告编号': report_form_data['textField_lp93kxup'],
                })
                return
            financial_process = yida_client.get_approve_history(
                financial_InstanceId,
                admin_user_id
            )
            # print('financial_process',financial_process)
            # 收款状态
            collection_status = "未知"
            for financial_process_item in financial_process:
                if financial_process_item.type == 'TODO':
                    show_name = financial_process_item.show_name
                    if show_name =='待预算':
                        cache_data["process_status"] = '待预算'
                        collection_status = '未收款'
                    elif show_name =='结算':
                        cache_data["process_status"] = '结算'
                        collection_status = '部分已收'
                    elif show_name =='结清':
                        cache_data["process_status"] = '结清'
                        collection_status = '已收'
                    break
            value = json.dumps(cache_data,skipkeys=True)
            key = f"chengxiang:form_data:{finicial_form_uuid}:{financial_data.form_data.get('textField_ltmbnezf')}"
            print("已记录缓存")
            cache.set(key,value,timeout=None)
    # 登记日期
    date_of_registration = report_form_data['dateField_lp92f309']
    # 转换为秒级别的时间戳
    timestamp_s = date_of_registration / 1000
    # 时区差异，对于北京时间是UTC+8
    tz_beijing = timezone(timedelta(hours=8))
    # 使用时区感知的方式来转换时间戳
    date = datetime.fromtimestamp(timestamp_s, tz=tz_beijing)
    # 格式化日期
    date_str = date.strftime('%Y/%m/%d')
    # 地区
    area = report_form_data['cascadeSelectField_lpgahbwq']
    # 归属地
    Attribution = '省外'
    # 县级归属地
    county = '无'
    if(len(area)>1):
        Attribution = area[1]
        county = area[2]
    else:
        Attribution = area[0]
    # 委托方
    clients = report_form_data['textField_lphpacz4']
    # 工程名称
    project_name = report_form_data['textField_lphpacz0']
    # 报告编号 report_code
    report_code = report_form_data['textField_lp93kxup']
    # 总面积
    total_area = report_form_data['textField_lp93kxwo']
    if total_area == '':
        total_area = '0'  
    # 单价
    price = report_form_data['textField_lp93kxwp']
    if price == '':
        price = '0' 
    if financial_data:
        if (isinstance(financial_data,dict)):
            financial_form_data = financial_data.get("form_data")
        else:
            financial_form_data = financial_data.form_data
    else:
        financial_form_data = {}
        collection_status = '未收款'
    # 总检测费
    if(collection_status == "未收款"):
        total_price = report_form_data.get('textField_lp93kxwq',0)
    else:
        total_price = financial_form_data.get("numberField_lv0lyit8_value",0)
    # 公司收款 companyCollection
    companyCollection = financial_form_data.get('numberField_lv0lyit9_value',0)
    # 业务员收款 salesmanCollection
    salesmanCollection = financial_form_data.get('numberField_lv0lyita_value',0)
    # 管理费 managementCost
    managementCost = financial_form_data.get('numberField_lv0lyitb_value',0)
    # 税额 receiptTaxAmount
    receiptTaxAmount = financial_form_data.get('numberField_lv0lyitc_value',0)
    # 其他款项 otherAmount
    otherAmount = financial_form_data.get('numberField_lv0lyite_value',0)
    # 其他税额 otherTaxAmount
    otherTaxAmount = financial_form_data.get('numberField_lv0lyitf_value',0)
    # 社保金额 socialSecurityAmount
    socialSecurityAmount = financial_form_data.get('numberField_lv0lyith_value',0)
    # 结算金额 settlementAmountTotal
    settlementAmountTotal = financial_form_data.get('numberField_lv0lyiti_value',0)
    data_dict = {
        '登记日期': date_str,
        '归属地': Attribution,
        '县级归属地': county,
        '委托方': clients,
        '工程名称': project_name,
        '报告编号': report_code,
        '总面积': total_area,
        '单价': price,
        '总检测费': total_price,
        '公司收款': companyCollection,
        '业务员收款': salesmanCollection,
        '管理费': managementCost,
        '税额': receiptTaxAmount,
        '其他款项': otherAmount,
        '其他税额': otherTaxAmount,
        '社保金额': socialSecurityAmount,
        '结算金额': settlementAmountTotal,
        '收款状态': collection_status
    }
    print('数据',data_dict)
    results_queue.put(data_dict)



@csrf_exempt
@require_http_methods(["POST"])
def generate_report(request,uuid_string):
    try:
        report_model = RepModel.objects.get(uuid=uuid_string)
    except RepModel.DoesNotExist:
        return ApiResponse.fail(message="未找到模板.")
    datasource: dict[str, any] = json.loads(request.body)
    render_data = datasource["render_data"]
    attachment_info = datasource["attachment_info"]
    download_url = attachment_info.get("download_url")
    full_download_url = yida_client.get_full_download_url(
        user_id=admin_user_id, download_url=download_url)
    response = requests.get(full_download_url.body.result)
    if response.status_code == 200:
        file_content = response.content
        render_record = DocxRenderRecord(
            render_data=render_data,
            company_name="浙江城乡检测",
            model_id=report_model.id
        )
        report_path = rf"out-pdf/{datetime.now().strftime('%Y%m')}/{render_record.task_id}"
        create_directories_if_not_exist(
            [rf"{tmp_path}/{report_path}"])  # 创建报告缓存路径
    try:
        tmp_file_path = rf"{tmp_path}/{report_model.path}"
        if not os.path.exists(tmp_file_path):
            create_directories_if_not_exist([tmp_file_path])
            print(f"缓存模板不存在，从oss下载>>>>>>>")
            if bucket.object_exists(report_model.path):
                print("文件已找到>>>>>>")
            bucket.get_object_to_file(report_model.path, tmp_file_path)
            print(f"模板下载成功>>>>>>>")
        else:
            print(f"本地模板文件已找到{tmp_file_path}")
        def generateReportPdf():
            doc = DocxTemplate(tmp_file_path)
            renderData = compile_tpl_data(doc, render_data)
            doc.render(renderData)
            outdocpath = f"{report_path}/cover.docx"
            doc.save(f"{tmp_path}/{outdocpath}")
            # outPdfpath = f"{report_path}origin.pdf"
            convert_to_pdf(
                f"{tmp_path}/{outdocpath}", f"{tmp_path}/{report_path}")
            content_path = rf"{tmp_path}/{report_path}/content.pdf"
            with open(content_path, 'wb') as out:
                out.write(file_content)
            # 合成pdf
            merge_pdfs([rf"{tmp_path}/{report_path}/cover.pdf",
                        content_path], rf"{tmp_path}/{report_path}/origin.pdf")
            print(f"正在保存完整报告>>>>>>>")
            render_record.origin_pdf_path = rf"{report_path}/origin.pdf"
            bucket.put_object_from_file(
                render_record.origin_pdf_path, rf"{tmp_path}/{render_record.origin_pdf_path}")
            render_record.save()
            form_uuid = attachment_info.get("form_uuid")
            component_id = attachment_info.get("component_id")
            form_inst_id = attachment_info.get("form_inst_id")
            url = rf"https://api.zjcxjc.cn/api/v1/yida-app/common/download_file/{render_record.origin_pdf_path}"
            yida_client.update_form_data_by_id(form_uuid,admin_user_id,form_inst_id,{
                        component_id:[
                            {
                              "downloadUrl": url,
                              "name": "origin.pdf",
                              "previewUrl": url,
                              "url": url,
                              "ext": "pdf"
                            }
                          ]
                    })
            print("报告同步完成>>")

        thread = threading.Thread(target=generateReportPdf)
        thread.start()
        print(f"报告生成中>>>>>>>")
        return ApiResponse.success(message=f"报告{render_record.task_id}数据已导入,正在生成报告，请稍后")
    except ValueError:
        return ApiResponse.fail(message="Invalid UUID format.")
    except Exception:
        return ApiResponse.fail(message=f"报告生成失败")
    

def get_fake_sign_report(request):
    '''查看伪签名报告'''
    report_code = request.GET.get('reportCode')
    report = Report.objects.get(report_code=report_code)
    if not report.digital_sign_order_no:
        return ApiResponse.fail(message=rf"报告未生成，请在发起签署后打印")
    result = xm_digital_sign_client.get_completed_sign_records(report.digital_sign_order_no)
    if result.get("code") == 200:
        completed_records = result.get("data")
        participants = [{
            "dingtalkUserId":record.get("dingtalkUserId"),
            "coordinate":record.get("coordinate"),
        } for record in completed_records if not record.get("sealFilePath")]
        fake_pdf_path = fake_sign(report.report_path,participants)
        params = {'response-content-disposition': 'inline'}
        url = bucket.sign_url('GET', fake_pdf_path, 3600, params=params)
        return ApiResponse.success(data=url)
    else:
        return ApiResponse.fail(message=rf"报告未生成，请在发起签署后打印")
# 返回完整报告内容
def get_whole_report(request):
    report_code = request.GET.get('reportCode')
    is_admin = request.GET.get('isAdmin',None)
    report = Report.objects.get(report_code=report_code)
    if report.digital_sign_order_no:
        if not is_admin:
            sign_order_res = xm_digital_sign_client.get_sign_order(report.digital_sign_order_no)
            if sign_order_res.get("code") == 200:
                if sign_order_res.get("data").get("completedDate"):
                    is_admin = True
        if is_admin:
            result = xm_digital_sign_client.get_signed_pdf(report.digital_sign_order_no)
            if result.get("code") == 200:
                return ApiResponse.success(message=rf"报告已找到", data=result.get("data"))
            else:
                return ApiResponse.fail(message=result.get("message"))
    path = rf"{report.report_path}/whole.pdf"
    path_bak = rf"{report.report_path}/whole_print.pdf"
    # 创建限速下载文件的签名URL, 有效期60s。
    params = {'response-content-disposition': 'inline'}
    if (bucket.object_exists(path)):
        url = bucket.sign_url('GET', path, 3600, params=params)
        return ApiResponse.success(message=rf"报告已找到", data=url)
    elif (bucket.object_exists(path_bak)):
        url = bucket.sign_url('GET', path_bak, 3600, params=params)
        return ApiResponse.success(message=rf"报告已找到", data=url)
    else:
        return ApiResponse.fail(message=rf"报告未找到")


    # 解析模板json


def compile_tpl_data(tpl: DocxTemplate, datasource: dict):
    renderData = {}
    for key, value in datasource.items():
        if isinstance(value, str):
            try:
                json_value = json.loads(value)
                tmp_value = compile_tpl_data(tpl, {key: json_value})
                renderData[key] = tmp_value[key]
            except:
                renderData[key] = value
            continue
        if isinstance(value, list):
            clist = []
            for item in value:
                sub_opt = {
                    key: item
                }
                clist.append(compile_tpl_data(tpl, sub_opt))
                renderData[key] = clist
            continue
        if isinstance(value, (int, float)):
            renderData[key] = str(value)
        if isinstance(value, dict):
            if 'type' not in value:
                return compile_tpl_data(tpl, value)
            if value["type"] == "qrcode":
                url = genQrCode(value["text"])
                renderData[key] = InlineImage(tpl,
                                              image_descriptor=url, width=Mm(value["width"]))
            elif value["type"] == "img":
                renderData[key] = InlineImage(tpl,
                                              image_descriptor=value["url"], width=Mm(value["width"]))
            elif value["type"] == "date":
                timestamp = int(value["value"]) / 1000
                dt_object_utc = datetime.fromtimestamp(
                    timestamp, tz=timezone.utc)
                timezone_offset = 8  # Change this as per your local timezone
                local_timezone = timezone(timedelta(hours=timezone_offset))
                dt_object_local = dt_object_utc.astimezone(local_timezone)
                renderData[key] = dt_object_local.strftime(value["format"])
            continue
    return renderData


# 生成二维码图片


def genQrCode(qr_text):
    qr = qrcode.QRCode(
        version=1,
        error_correction=qrcode.constants.ERROR_CORRECT_L,
        box_size=10,
        border=4,
    )
    qr.add_data(qr_text)  # 这里填写你想转换成二维码的文本
    qr.make(fit=True)
    img = qr.make_image(fill_color="black", back_color="white")
    img_byte_arr = io.BytesIO()
    img.save(img_byte_arr, format='PNG')
    img_byte_arr.seek(0)
    return img_byte_arr

# 生成pdf

def convert_to_pdf(input_file_path, output_dir):
    print("正在生成pdf")
    # LibreOffice 命令行
    cmd = [
        "soffice",
        "--headless",
        "--convert-to",
        "pdf",
        "--outdir",
        output_dir,
        input_file_path
    ]
    subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    return 


@csrf_exempt
@require_http_methods(["POST"])
# 批量生成报告
def batch_generation_report(request):
    try:
        data = json.loads(request.body)
        userId = data.get("uuid", "")                # 发起人uuid
        number_str = data.get("number", "1")       # 数量
        try:
            number = int(number_str)  # 如果是整数
        except ValueError:
            number = 1  # 如果无法转换，给出默认值
        form_inst_id = data.get("form_inst_id", "")  
        print(f'参数--->formInstId: {form_inst_id}, 发起人userId: {userId}, 数量: {number}')
        report_data = yida_client.get_form_items_by_ids(
            report_form_uuid,
            form_inst_id,
            userId
        )
        form_data_json = report_data[0].form_data
        thread = Thread(target=batch_generation_report_background_task, args=(userId, number, form_data_json))
        thread.start()
        return ApiResponse.success(message=rf"正在批量生成")
    except Exception as e:
        return  ApiResponse.fail(message=rf"批量生成失败")

# 
def batch_generation_report_background_task(userId,number,form_data_json):
    max_retries = 3
    # report_code_last = form_data_json['textField_lp93kxup']
    # print('编号--->',report_code_last)
    form_data_json['numberField_lqd7xome'] = 1
    form_data_json['textField_lvg2c3u6'] = ''
    form_data_json['textField_m0wjwsev'] = str(uuid.uuid4())
    form_data_json["cascadeSelectField_m57rqgji"] = ["test"]
    filtered_res = {key: value for key, value in form_data_json.items() if key.endswith('_id')}
    for key, value in filtered_res.items():
        # print(f"{key}: {value}")
        form_data_json[key.split('_id')[0]] = value
    # 删除对应的键
    for key in filtered_res.keys():
        del form_data_json[key]
    # print('修改后的', form_data_json)
    for index in range(number-1):
        print('index--->',index)
        retries = 0
        while retries < max_retries:
            try:
                # 发起新流程
                yida_client.create_process_instance(
                    report_form_uuid,
                    userId,
                    form_data_json,
                    'TPROC--U0A66091AZQGSDPIFBEQP8HN89KL39DYDE7QLO7'
                )
                break  # 成功则跳出循环
            except Exception as e:
                print(f"重试 {retries + 1} 失败: {str(e)}")
                retries += 1
                time.sleep(1)  # 等待1秒再重试
        if retries == max_retries:
            logger.info(f"编号创建失败，已达到最大重试次数。")
            

@csrf_exempt
@require_http_methods(["GET"])
def update_bzy(request):
    bzy_name = request.GET.get('name')
    form_uuid = report_form_uuid
    if not bzy_name:
        return ApiResponse.fail("请选择需要同步的编制员")
    person_form_uuid = "FORM-861F9E6F4AAE4D73A255247BF7991765XAKG"
    person_res = yida_client.get_form_data_by_search_field(person_form_uuid,admin_user_id,[
        {
          "type": "TEXT",
          "operator": "eq",
          "componentName": "TextField",
          "key": "textField_lp0tv654",
          "value": bzy_name
        }
      ])
    person_instance = person_res[0].form_data
    person_id = person_instance.get("textField_lp0zbal4")
    Thread(target=update_bzy_task, args=(bzy_name,form_uuid,person_id)).start()
    return ApiResponse.success(f"发起同步编制人任务")

def update_bzy_task(bzy_name,form_uuid,person_id):
    form_instances,total = yida_client.get_all_form_data_by_search_field(form_uuid,admin_user_id,[
      {
        "type": "TEXT",
        "operator": "eq",
        "componentName": "TextField",
        "key": "textField_lrd6lxm1",
        "value": bzy_name
      }
    ])
    for index,item in enumerate(form_instances):
        form_data = item.form_data
        print(f"正在处理第{index+1}份报告：{form_data.get('textField_lp93kxup')}")
        form_inst_id = item.form_instance_id
        name = form_data.get('textField_lrd6lxm1') # 编制人name
        bzy_select = form_data.get('selectField_lqwcqyd0') #编制员
        bzy_select_id = form_data.get('selectField_lqwcqyd0_id')
        if (not bzy_select_id) or (name == bzy_select) or (bzy_select_id == person_id):
            continue
        else:
            result = yida_client.update_form_data_by_id(form_uuid,admin_user_id,form_inst_id,{
                "selectField_lqwcqyd0":person_id,
            })
            print(f"result>>>>>>{result}")
@csrf_exempt
@require_http_methods(["GET"])
def archive(request):
    start_time = request.GET.get('start_time')
    end_time = request.GET.get('end_time')
    form_uuid = report_form_uuid
    if not start_time or not end_time:
        return ApiResponse.fail("请选择时间范围")
    form_instances = yida_client.get_form_data_by_date_range(
        form_uuid=form_uuid,
        userId=admin_user_id,
        start_time=start_time,
        end_time=end_time, # 不包含该时间
        dynamic_order=None,
        )
    Thread(target=start_backup_task, args=(form_instances,form_uuid)).start()
    return ApiResponse.success(f"成功发起备份任务，共{len(form_instances)}个任务")

def archive_v2(request):
    reports = Report.objects.filter(is_backup=False).order_by('-created_at')[:1000]
    threading.Thread(target=archive_task, args=(reports,)).start()
    return ApiResponse.success(f"成功发起备份任务，共{len(reports)}个任务")


def archive_task(reports:list):
    form_uuid = report_form_uuid
    for report in reports:
        report_code = report.report_code
        result = yida_client.get_form_data_by_search_field(form_uuid,admin_user_id,[
          {
            "type": "TEXT",
            "operator": "eq",
            "componentName": "TextField",
            "key": "textField_lp93kxup",
            "value": report_code
          }
        ])
        print(f"report_code>>>>>>{report_code}")
        start_backup_task(result,form_uuid)

def start_backup_task(form_instances,form_uuid):
    for index,item in enumerate(form_instances):
        # if index < 166:
        #     continue
        print(f"正在处理第{index+1}份报告：{item.form_data.get('textField_lp93kxup')}")
        logger.info(f"正在处理第{index+1}份报告：{item.form_data.get('textField_lp93kxup')}")
        try:
            report = Report.objects.get(report_code=item.form_data.get('textField_lp93kxup'))
        except Report.DoesNotExist:
            print(f"未找到报告：{item.form_data.get('textField_lp93kxup')}")
            continue
        except Report.MultipleObjectsReturned:
            print(f"找到多个报告：{item.form_data.get('textField_lp93kxup')}")
            reports = Report.objects.filter(report_code=item.form_data.get('textField_lp93kxup')).order_by('-created_at')
            if reports.exists():
                report = reports.first()
                print(f"找到多个报告，取最新报告：{report}")
            else:
                print(f"未找到报告：{item.form_data.get('textField_lp93kxup')}")
                continue
        except Exception as e:
            print(f"处理报告时发生错误：{e}")
            continue
        report_path = report.report_path
        print(f"正在备份报告：{report.report_code}")
        try:
            bak_attachment(item,"attachmentField_lpb2cdkb",report_path,form_uuid)
            bak_attachment(item,"attachmentField_lpb2cdka",report_path,form_uuid)
            bak_attachment(item,"attachmentField_lpb2cdkd",report_path,form_uuid)
            bak_attachment(item,"attachmentField_lpb2cdkf",report_path,form_uuid)
            bak_attachment(item,"attachmentField_lqrz4ehj",report_path,form_uuid)
        except Exception as e:
            print(f"未知错误：{e}")
            continue
        report.is_backup = True
        report.save()
        print("备份成功")
        time.sleep(3)
    

def bak_attachment(form_inst_data,field_name,report_path,form_uuid,retry=3):
    try:
        print("备份地址"+report_path)
        if field_name not in form_inst_data.form_data:
            print(f"{field_name}该字段无值")
            return
        attachments = json.loads(form_inst_data.form_data[field_name])
        new_attachments = []
        for index,attachment in enumerate(attachments):
            download_url:str = attachment.get("downloadUrl")
            if download_url.startswith("https://api.zjxmyq.cn") or download_url.startswith("https://api.zjcxjc.cn"):
                print(f"{field_name}已备份，无需重复备份")
                new_attachments.append(attachment)
                continue
            full_download_url = yida_client.get_full_download_url(admin_user_id,download_url,True)
            response = requests.get(full_download_url.body.result)
            if response.status_code == 200:
                file_content = response.content
                oss_path = f"{report_path}/{field_name}/{index}-{attachment.get('name')}"
                bucket.put_object(oss_path, file_content)
                xm_url = f"https://api.zjcxjc.cn/api/v1/yida-app/common/download_file/{oss_path}"
                new_attachment = {
                        "downloadUrl": xm_url,
                        "name": attachment.get('name'),
                        "previewUrl": xm_url,
                        "url": xm_url,
                        "ext": attachment.get('name').split('.')[-1]
                    }
                new_attachments.append(new_attachment)
        yida_client.update_form_data_by_id(form_uuid, admin_user_id, form_inst_data.form_instance_id, {
                    field_name: new_attachments
                })
        print(f"{field_name}备份成功")
    except Exception as e:
        print(f"宜搭接口调用错误：{e}")
        retry -= 1
        if retry > 0:
            bak_attachment(form_inst_data,field_name,report_path,form_uuid,retry)

@csrf_exempt
@require_http_methods(["POST"])
def modify_report(request):
    # 获取原始请求体数据
    req_data = json.loads(request.body)  # 假设请求体是JSON格式
    report_code_arr = req_data.get("reportCodeArr")
    update_data = req_data.get("updateData")
    for report_code in report_code_arr:
        print(f"report_code is {report_code}")
        report_info = YidaClient.get_ids_by_search_field(
            form_uuid=report_form_uuid, userId=req_data.get("user_id",admin_user_id), search_field={"textField_lp93kxup": report_code})
        if (report_info):
            report_instid = report_info[0]
            update_res = YidaClient.update_form_data_by_id(
                form_uuid=report_form_uuid, userId=req_data.get("user_id",admin_user_id), form_inst_id=report_instid, update_field=update_data)
            if (update_res != "success"):
                return ApiResponse.fail(message=f"报告{report_code}修改失败")
    return ApiResponse.success(message="修改成功")
# 超过一月未到总工冻结
@csrf_exempt
@require_http_methods(["GET"])    
def refuse_to_register(request):
    all_data = []
    # 计算30天前的日期
    date_30_days_ago = datetime.now() - timedelta(days=30)
    # 计算60天前的日期
    date_60_days_ago = datetime.now() - timedelta(days=60)
    # 转换为时间戳
    timestamp_30 = int(date_30_days_ago.timestamp() * 1000)
    print('timestamp--->',timestamp_30)
    timestamp_60 = int(date_60_days_ago.timestamp() * 1000)
    print('timestamp--->',timestamp_60)
    result_30,_ = yida_client.get_all_ids_by_search_field(report_form_uuid,
                                            admin_user_id,
                                            [{
                                                "key": "currentNodeName",
                                                "value": ["待写报告", "待审核"],
                                                "type": "ARRAY",
                                                "operator": "contains",
                                                "componentName": "TextField"
                                            },
                                            {
                                                "key": "dateField_lp92f309",
                                                "value": timestamp_30,
                                                "type": "DOUBLE",
                                                "operator": "lt",
                                                "componentName": "DateField"
                                            },
                                            {
                                                "key":"selectField_lp9egpd9",
                                                "value":["材料","鉴定","金华分公司","衢州公司","典型","比对","桥隧","幕墙","节能","地基","通用","评估","空气","结构","钢构","监测"],
                                                "type":"ARRAY",
                                                "operator":"contains",
                                                "componentName":"SelectField"
                                            }
                                            ])

    all_data.extend(result_30)
    print('<><><><><><><><><><><><><>')
    result_60,_ = yida_client.get_all_ids_by_search_field(report_form_uuid,
                                            admin_user_id,
                                            [{
                                                "key": "currentNodeName",
                                                "value": ["待写报告", "待审核"],
                                                "type": "ARRAY",
                                                "operator": "contains",
                                                "componentName": "TextField"
                                            },
                                            {
                                                "key": "dateField_lp92f309",
                                                "value": timestamp_60,
                                                "type": "DOUBLE",
                                                "operator": "lt",
                                                "componentName": "DateField"
                                            },       
                                            {
                                                "key":"selectField_lp9egpd9",
                                                "value":["产品","纠纷","司法","设计","造价"],
                                                "type":"ARRAY",
                                                "operator":"contains",
                                                "componentName":"SelectField"
                                            }
                                            ]
                                            )
    all_data.extend(result_60)
    thread = Thread(target=refuse_to_register_task, args=(all_data,))
    thread.start()
    return ApiResponse.success(message='获取数据')

def refuse_to_register_task(all_data):
    unique_data = []
    for i, data in enumerate(all_data):
        value = cache.get(f'timeout_freeze_compiler:{data}')
        if i == 0:
            print('value--->',value,data)
        if value != '1':
            unique_data.append(data)
            cache.set(f'timeout_freeze_compiler:{data}', '1', timeout=10*24*60*60)  # 10天的秒数
    print('新增的过期数据--->',len(unique_data),unique_data) 
    
    need_freeze_personnel = []   # 需要冻结的人
    for index, item in enumerate(unique_data):
        # print(index,item)
        examine_approve_item = yida_client.get_form_items_by_ids(
            report_form_uuid,
            item,
            admin_user_id   
        )
        # print('examine_approve_item--->',examine_approve_item[0].form_data['multiSelectField_lqwcqyd1'])
        need_freeze_personnel.extend(examine_approve_item[0].form_data['multiSelectField_lqwcqyd1'])
        # break
    # 去重
    need_freeze_personnel_norepetition = list(dict.fromkeys(need_freeze_personnel))
    print('需冻结的编制员--->',need_freeze_personnel_norepetition)
    print('len--->',len(need_freeze_personnel_norepetition))
    
    # 需过滤掉的指定id
    need_filtered_id = [
        '132058133925879495',
        '4302516026430609',
        '383267142424342951'
    ]
    for index,item in enumerate(need_filtered_id):
        if item in need_freeze_personnel_norepetition:
            need_freeze_personnel_norepetition.remove(item)
    print('过滤后需要冻结的编制员--->',need_freeze_personnel_norepetition)
    print('len--->',len(need_freeze_personnel_norepetition))
    
    for index, item in enumerate(need_freeze_personnel_norepetition):
        yida_client.update_form_data_by_field(
            'FORM-861F9E6F4AAE4D73A255247BF7991765XAKG',
            admin_user_id,
            {
                "textField_lp0zbal4":item
            },
            {
                "selectField_lygntf4y":"冻结"
            }
        )
    

  
# 更正申请  
@csrf_exempt
@require_http_methods(["GET"])
def modify_application(request):
    start_report = request.GET.get('start_report')
    end_report = request.GET.get('end_report')
    # 提取前缀和数字部分
    start_prefix = start_report[:-5]
    end_prefix = end_report[:-5]
    try:
        start_num = int(start_report[-5:])
        end_num = int(end_report[-5:])
    except ValueError:
        return ApiResponse.fail(message='Invalid report numbers')
    # 检查前缀是否一致
    if start_prefix != end_prefix:
        return ApiResponse.fail(message='The prefixes of start_report and end_report must be the same')
    # 生成包括start_report和end_report在内的所有编号
    report_numbers = [f"{start_prefix}{str(num).zfill(5)}" for num in range(start_num, end_num + 1)]
    thread = Thread(target=modify_application_task, args=(report_numbers,))
    thread.start()
    return ApiResponse.success(message='正在进行更正,请稍等。。。')

def modify_application_task(report_numbers):
    print('report_numbers-->',report_numbers)
    for index, item in enumerate(report_numbers):
        print('----->',item)           
        form_inst_id =  yida_client.get_ids_by_search_field(
            report_form_uuid,
            admin_user_id,
            {
                "textField_lp93kxup":item
            }
        )
        print('form_inst_id--->',form_inst_id)
        report_form = yida_client.get_form_items_by_ids(
            report_form_uuid,
            form_inst_id[0],
            admin_user_id,
        )
        print(report_form[0].form_data['textField_ltmlzgdv'])            
            
        try:
            report_form_json = json.loads(report_form[0].form_data['textField_ltmlzgdv'])
            if 'report_code' in report_form_json:
                print('json中有report_code',report_form_json['report_code'])
                match = re.search(r'G(\d+)', report_form_json['report_code'])
            else:
                print('json中没有report_code')
                match = re.search(r'G(\d+)', item)
                
            if match:
                number_after_g = int(match.group(1)) + 1
                new_report_code = re.sub(r'G(\d+)', f'G{number_after_g}', report_form_json['report_code'])
                print('有match',match,number_after_g,new_report_code)
            else:
                new_report_code = item.split('-')[0] + 'G1'+'-'+item.split('-')[1]+'-'+item.split('-')[2]
            report_form_json['report_code'] = new_report_code
            print("JSON解析成功:", report_form_json)
        except json.JSONDecodeError:
            print("解析错误：提供的字符串不是有效的JSON格式")
            match = re.search(r'G(\d+)', item)
            if match:
                number_after_g = int(match.group(1)) + 1
                new_report_code = re.sub(r'G(\d+)', f'G{number_after_g}', item)
            else:
                new_report_code = item.split('-')[0] + 'G1'+'-'+item.split('-')[1]+'-'+item.split('-')[2]
            report_form_json = {
                "report_code":new_report_code
            }
        yida_client.update_form_data_by_id(
            report_form_uuid,
            admin_user_id,
            form_inst_id[0],
            {
                "textField_ltmlzgdv":json.dumps(report_form_json)
            }
        )



# 生成报告封面
@csrf_exempt
@require_http_methods(["POST"])
def generate_base_report(request, uuid_string):
    try:
        report_model = RepModel.objects.get(uuid=uuid_string)
    except RepModel.DoesNotExist:
        return ApiResponse.fail(message="未找到模板.")
    datasource: dict[str, any] = json.loads(request.body)
    form_uuid = report_form_uuid
    form_inst_id = datasource["formInstId"]  # 获取数据源中的表单实例ID
    inst_res = yida_client.get_form_items_by_ids(form_uuid, form_inst_id, admin_user_id)
    if not inst_res:
        return ApiResponse.fail(message="未找到该报告数据.")
    form_data = inst_res[0].form_data
    report_type = form_data.get("selectField_lp9egpd9")
    area = form_data.get("cascadeSelectField_lpgahbwq_id")
    datasource["工程名称"] = form_data.get("textField_lphpacz0")
    datasource["委托单位"] = form_data.get("textField_lphpacz4")
    datasource["报告名称"] = form_data.get("selectField_lpb4vtbt")
    datasource["设计单位"] = form_data.get("textField_lpgut0nt")
    datasource["勘察单位"] = form_data.get("textField_lpgut0nr")
    datasource["施工单位"] = form_data.get("textField_lpgut0nq")
    datasource["监理单位"] = form_data.get("textField_lpgut0ns")
    datasource["工程地址"] = form_data.get("textField_lphrnneu")
    datasource["评估类别"] = form_data.get("selectField_lp93kxv5")
    datasource["检测类别"] = form_data.get("selectField_lp93kxv5")
    datasource["样品名称"] = form_data.get("textField_lr0cupsi")
    datasource["工程类别"] = form_data.get("selectField_lp93kxv5")
    datasource["监管编号"] = form_data.get("textField_lpb5xuuu")
    datasource["报告标题"] = form_data.get("textField_lv25b13o")
    datasource["司法编号"] = form_data.get("textField_lpb5xuup")
    
    if form_data.get("textField_ltmlzgdv"):
        sign_info = form_data.get("textField_ltmlzgdv")
        try:
            data_dict = json.loads(sign_info)  # 假设输入总是合法的JSON格式
            
            # 检查是否包含键 'report_code'
            if 'report_code' in data_dict:
                print("报告代码:", data_dict['report_code'])
                datasource["报告编号"] = data_dict['report_code']
            else:
                # 如果不包含所需的键，则设置datasource中的默认值
                datasource["报告编号"] = form_data.get("textField_lp93kxup")
        except:
            datasource["报告编号"] = form_data.get("textField_lp93kxup")    
    else:
        # 如果字符串为空，也设置datasource中的默认值
        datasource["报告编号"] = form_data.get("textField_lp93kxup")    
        
        
    report_code = form_data.get("textField_lp93kxup")
    datasource["二维码"] =  {
                     "type":"qrcode",
                     "width":30,
                     "text":report_code
                 }
    
    if form_data.get("dateField_lp93kxx6"):
        datasource["检测日期"] = {
                    "type": "date",
                    "value": form_data.get("dateField_lp93kxx6"),
                    "format":"%Y年%m月%d日"
                }
    if form_data.get("dateField_lpgnxeft"):
        datasource["分隔符"] = "-"
        datasource["检测日期至"] = {
                    "type": "date",
                    "value": form_data.get("dateField_lpgnxeft"),
                    "format":"%Y年%m月%d日"
                }
    if form_data.get("dateField_lpb39cyx"):
        datasource["签发日期"] = {
                    "type": "date",
                    "value": form_data.get("dateField_lpb39cyx"),
                    "format":"%Y年%m月%d日"
                }
    jcr1_id = get_user_id_in_form_data(form_data,"selectField_lpgut0ng")
    print('jcr1_id',jcr1_id)
    if jcr1_id:
        jcr1, _ = get_user_by_yida_user_id(
            jcr1_id, report_code)
        datasource["检测人1"] = jcr1['name']

    jcr2_value = form_data.get("selectField_lqeidrd3")
    if jcr2_value:
        if("-" in jcr2_value):
            jcr2_id = jcr2_value.split("-")[1]
        else:
            jcr2_id = jcr2_value
        if (jcr2_id):
            jcr2, _ = get_user_by_yida_user_id(
                jcr2_id, report_code)
            datasource["检测人2"] = jcr2['name']
        
    shr_value = form_data.get("employeeField_lpkl919z_id")
    if shr_value:
        shr_id = shr_value[0]
        shr, sign_method = get_user_by_yida_user_id(
            shr_id, report_code)
        if (sign_method == "钉钉签名"):
            if "digitalSignatureField_lqrz4eha" in form_data:
                shr["sign_arr"] = form_data["digitalSignatureField_lqrz4eha"]
        datasource["审核人"] = shr['name']
    app_history = yida_client.get_approve_history(form_inst_id,admin_user_id)
    pzr_node = next((item for item in reversed(app_history) if item.show_name == "总工审核"), None)

    if pzr_node:
        pzr, sign_method = get_user_by_yida_user_id(
            pzr_node.operator_user_id, report_code)
        if (sign_method == "钉钉签名"):
            if "digitalSignatureField_lqdi3j6t" in form_data:
                pzr["sign_arr"] = form_data["digitalSignatureField_lqdi3j6t"]
        datasource["批准人"] = pzr['name']

    group_leader_id = get_user_id_in_form_data(form_data,"selectField_lqvpbi42")
    if (group_leader_id):
        group_leader, _ = get_user_by_yida_user_id(
            group_leader_id, report_code)
        datasource["组长"] = group_leader['name']
        datasource["从事专业_组长"] = group_leader.get("subject","")
        datasource["技术职称_组长"] = group_leader.get("job_title","")

    group_user1_id = get_user_id_in_form_data(form_data,"selectField_lqvpbi43")
    if (group_user1_id):
        group_user1, _ = get_user_by_yida_user_id(
            group_user1_id, report_code)
        datasource["组员一"] = group_user1['name']
        datasource["从事专业_组员一"] = group_user1.get("subject","")
        datasource["技术职称_组员一"] = group_user1.get("job_title","")

    group_user2_id = get_user_id_in_form_data(form_data,"selectField_lqvpbi45")
    if (group_user2_id):
        group_user2, _ = get_user_by_yida_user_id(
            group_user2_id, report_code)
        datasource["组员二"] = group_user2['name']
        datasource["从事专业_组员二"] = group_user2.get("subject","")
        datasource["技术职称_组员二"] = group_user2.get("job_title","")
    temp_dir = tempfile.mkdtemp()
    urlstr = form_data['attachmentField_lqrz4ehj']  # 获取上传的报告主体文件
    report_content_info = json.loads(urlstr)[0]
    file_name = report_content_info["name"]
    ext = file_name.split(".")[-1]
    file_down:str = report_content_info["downloadUrl"]
    if file_down.startswith("https://api.zjxmyq.cn") or file_down.startswith("https://api.zjcxjc.cn"): # 已归档到oss
        file_down = file_down.replace("#","%23")
        response = requests.get(file_down)
    else:
        full_download_url = yida_client.get_full_download_url(
            user_id=admin_user_id, download_url=file_down)
        response = requests.get(full_download_url.body.result)
    if response.status_code == 200:
        file_content = response.content
        try:
            report = Report.objects.get(report_code=report_code)
        except Exception as err:
            report = Report(report_code=datasource["报告编号"],
                            model_id=report_model.id)
            report.report_path = rf"out-pdf/{datetime.now().strftime('%Y%m')}/{report.uuid}"
        # 获取报告页数
        tmp_report_path = rf"{tmp_path}/{report.report_path}"
        create_directories_if_not_exist([tmp_report_path])  # 创建报告缓存路径
        content_path = rf"{tmp_report_path}/content.{ext}"
        print(f"pdf 地址>>>>>{content_path}")
        with open(content_path, 'wb') as out:
            out.write(file_content)
        if ext == "docx":
            convert_to_pdf(content_path, tmp_report_path)
            content_path = rf"{tmp_report_path}/content.pdf"
        bucket.put_object_from_file(rf"{report.report_path}/content.pdf", content_path)
        try:
            with fitz.open(content_path) as doc_pdf:
                # 返回PDF的页数
                total_page = len(doc_pdf)
                datasource["全部页码"] = total_page + 1
            print(f"报告内容上传成功")
        except FileDataError:
            print("文件损坏或格式错误")
            return ApiResponse.fail(message="文件损坏或格式错误")
    try:
        tmp_file_path = rf"{tmp_path}/{report_model.path}"
        if not os.path.exists(tmp_file_path):
            create_directories_if_not_exist([tmp_file_path])
            print(f"缓存模板不存在，从oss下载>>>>>>>")
            if bucket.object_exists(report_model.path):
                print("文件已找到>>>>>>")
            bucket.get_object_to_file(report_model.path, tmp_file_path)
            print(f"模板下载成功>>>>>>>")
        else:
            print(f"本地模板文件已找到{tmp_file_path}")
        try:
            if jcr1 and "sign_arr" in jcr1:
                datasource["检测人签名1"] = {
                    "type": "img",
                    "url": download_sign(jcr1["sign_arr"],temp_dir),
                    "width": 30
                }
        except Exception as err:
            print("检测人签名1不存在")
        try:
            if jcr2 and "sign_arr" in jcr2:
                datasource["检测人签名2"] = {
                    "type": "img",
                    "url": download_sign(jcr2["sign_arr"],temp_dir),
                    "width": 30
                }
        except:
            print("检测人签名2不存在")
        try:
            if shr and "sign_arr" in shr:
                datasource["审核人签名"] = {
                    "type": "img",
                    "url": download_sign(shr["sign_arr"],temp_dir),
                    "width": 30
                }
        except:
            print("审核人签名不存在")
        try:
            if pzr and "sign_arr" in pzr:
                datasource["批准人签名"] = {
                    "type": "img",
                    "url": download_sign(pzr["sign_arr"],temp_dir),
                    "width": 30
                }
        except:
            print("批准人签名不存在")
        try:
            if group_leader and "sign_arr" in group_leader:
                datasource["组长签名"] = {
                    "type": "img",
                    "url": download_sign(group_leader["sign_arr"],temp_dir),
                    "width": 30
                }
        except:
            print("组长签名不存在")
        try:
            if group_user1 and "sign_arr" in group_user1:
                datasource["组员一签名"] = {
                    "type": "img",
                    "url": download_sign(group_user1["sign_arr"],temp_dir),
                    "width": 30
                }
        except:
            print("组员一签名不存在")
        try:
            if group_user2 and "sign_arr" in group_user2:
                datasource["组员二签名"] = {
                    "type": "img",
                    "url": download_sign(group_user2["sign_arr"],temp_dir),
                    "width": 30
                }
        except:
            print("组员二签名不存在")

        def generateReportPdf():
            doc = DocxTemplate(tmp_file_path)
            renderData = compile_tpl_data(doc, datasource)
            doc.render(renderData)
            outdocpath = f"{tmp_path}/{report.report_path}/cover.docx"
            doc.save(outdocpath)
            bucket.put_object_from_file(
                rf"{report.report_path}/cover.docx", outdocpath)
            tmpPdfpath = f"{tmp_path}/{report.report_path}"
            convert_to_pdf(
                outdocpath, tmpPdfpath)
            # 合成pdf
            merge_pdfs([rf"{tmp_path}/{report.report_path}/cover.pdf",
                        rf"{tmp_path}/{report.report_path}/content.pdf"], rf"{tmp_path}/{report.report_path}/whole.pdf")
            print(f"正在保存完整报告>>>>>>>")
            bucket.put_object_from_file(
                rf"{report.report_path}/whole.pdf", rf"{tmp_path}/{report.report_path}/whole.pdf")
            report.completed_at = datetime.now()
            report.digital_sign_order_no = None
            report.save()
            shutil.rmtree(temp_dir)
            print(f"报告已生成")
            if check_auto_create_sign_order(report_type,area):
                create_digital_sign_order_thread([form_inst_id],inst_res)
        thread = threading.Thread(target=generateReportPdf)
        thread.start()
        print(f"报告生成中>>>  >>>>")
        return ApiResponse.success(message=f"报告{report_code}数据已导入,正在生成报告，请稍后")
    except Report.DoesNotExist:
        return ApiResponse.fail(message="No record found with the provided UUID.", code=404)

    except ValueError:
        return ApiResponse.fail(message="Invalid UUID format.")
    except Exception as err:
        return ApiResponse.fail(message=f"报告生成失败")
        

def check_auto_create_sign_order(report_type,area):
    '''校验是否需要自动发起签署'''
    if report_type in ["司法","造价","设计","纠纷","产品","衢州公司"]:
        return False
    if area:
        area_city = area[-1]
        if report_type == "鉴定" and area_city in ["ZJ_J_JJ",
                                            "ZJ_J_HY",
                                            "ZJ_J_LQ",
                                            "ZJ_J_LH",
                                            "ZJ_J_WL",
                                            "ZJ_J_YH",
                                            "ZJ_J_TT",
                                            "ZJ_J_XJ",
                                            "ZJ_J_SM",
                                            "ZJ_C_RA"]:
            return False
    return True










# 根据user_id获取人员信息
def get_user_by_yida_user_id(user_id: str, report_code):
    user_form_uuid = "FORM-861F9E6F4AAE4D73A255247BF7991765XAKG"
    userinfo = yida_client.get_form_data_by_search_field(form_uuid=user_form_uuid, userId=admin_user_id, search_field=[
      {
        "type": "TEXT",
        "operator": "eq",
        "componentName": "TextField",
        "key": "textField_lp0zbal4",
        "value": user_id
      }
    ])
    user = {}
    if (userinfo):
        userinfo = userinfo[0].form_data
        user["name"] = userinfo["textField_lp0tv654"]
        user["subject"] = userinfo.get("textField_lqvoc0pq","")
        user["job_title"] = userinfo.get("textField_lqvoc0pr","")
        if "radioField_lqdk47dg" in userinfo:
            if (userinfo["radioField_lqdk47dg"] == "电子签名"):
                if "digitalSignatureField_lp0tv65b" in userinfo:
                    user["sign_arr"] = userinfo["digitalSignatureField_lp0tv65b"]
            elif (userinfo["radioField_lqdk47dg"] == "钉钉签名"):
                # 获取该流程下用户的签名
                qm_form_uuid = "FORM-36CB6E26E47043A4ADAE0C923F7E730DEW85"
                qminfo = yida_client.get_form_data_by_search_field(form_uuid=qm_form_uuid, userId=admin_user_id, search_field={
                    "textField_lqvmzy2z": report_code,
                    "textField_lqvmzy30": user_id
                })
                if (qminfo):
                    qminfo = qminfo[0].form_data
                    if "digitalSignatureField_lqvmzy35" in qminfo:
                        user["sign_arr"] = qminfo["digitalSignatureField_lqvmzy35"]
            return user, userinfo["radioField_lqdk47dg"]
        else:
            return None, None
        

def get_user_id_in_form_data(form_data,component_id,is_id=False):
    '''从表单中获取正确的user_id'''
    pattern = r'^[a-zA-Z0-9-]+$'
    user_value = form_data.get(component_id)
    print('user_value',user_value)
    if not user_value:
        return None
    if bool(re.match(pattern, user_value)):
        return user_value
    if "-" in user_value:
        user_value = user_value.split("-")[-1]
        if bool(re.match(pattern, user_value)):
            return user_value
    if not is_id:
        return get_user_id_in_form_data(form_data,component_id+"_id",True)
    return None


def download_sign(sign_url,direction_path):
    '''下载签名'''
    second_sign_res = requests.get(sign_url)
    if second_sign_res.status_code == 200:
        second_sign_img = second_sign_res.content
        sign_url = os.path.join(direction_path, f"{uuid.uuid4()}.png")
        with open(sign_url, "wb") as f:
            f.write(second_sign_img)
    return sign_url


@csrf_exempt
@require_http_methods(["POST"])
def foundation_install_statistics(request):
    '''基坑打印'''
    reqData = json.loads(request.body)
    model_id = 200
    form_uuid = "FORM-A103E5D737D74894AADA078ED12680FAYX6N"
    install_man = reqData.get("textField_lusmqf7r") or reqData.get("textField_lusmqf7s")
    result,total = yida_client.get_all_form_data_by_search_field(form_uuid,admin_user_id,reqData)
    search_date_range = reqData.get("dateField_lusmqf7o") or ["",""]
    if reqData.get("textField_lusmqf7r"):
        install_man_type = "主安装人"
        install_cost_key = "numberField_m1h95yt2"
    else:
        install_man_type = "副安装人"
        install_cost_key = "numberField_m1h95yt3"
    render_data = {
        "统计开始日期":date_format(search_date_range[0]),
        "统计结束日期":date_format(search_date_range[1]),
        "条件":",".join([str(value) for key, value in reqData.items() if key != "dateField_lusmqf7o" and value]),
        "安装人类别":install_man_type,
        "产品安装信息":[{
            **item.form_data,
            "安装人":install_man,
            "安装费": item.form_data.get(install_cost_key),
        } for item in result]
    }
    res = xm_client.render_model_xlsx(model_id,render_data)
    if(res.get("code")==200):
        return ApiResponse.success(data=res.get("data"))
    else:
        return ApiResponse.fail(message=res.get("message"))


@csrf_exempt
@require_http_methods(["GET"])
def foundation_preuse_sign(request):
    form_inst_id = request.GET.get("form_inst_id") # FINST-54A66HC1YT9O2IMN8VZM79DIGVG23CIGQ8M0MQ41
    form_uuid = "FORM-B03AFB7805D24FD9B5502EFC344AB5CFL4W1"
    result = yida_client.get_form_items_by_ids(form_uuid,form_inst_id,admin_user_id)
    if result:
        form_data = result[0].form_data
    else:
        return ApiResponse.fail(message="未找到该表单实例")
    table_data = form_data.get("tableField_m0kodbt8")
    pre_form_uuid = "FORM-EF4A47F1EEC549C4B2B8DC428F42C3475OBQ"
    for item in table_data:
        try:
            product = json.loads(json.loads(item.get("associationFormField_lz85phco_id")))
            res = yida_client.create_form_data(pre_form_uuid,admin_user_id,{
                "associationFormField_lz85jluh":[
                  {
                    "appType": 'APP_R3U6VT51DXVY8NTP4I0Z', 
                    "formType": 'receipt',
                    "formUuid": form_uuid,
                    "instanceId": form_inst_id,
                    "title": form_data.get("textField_lz95zyrg"),
                  },  
                ],# 项目名称
                "associationFormField_lz85phco":product,# 产品
                "textField_lzm251hb":product[0].get("title") if product else "",
                "numberField_lz85jlui":item.get("numberField_m0kodbt9"),
                "numberField_lz85jluj":item.get("numberField_m0kodbtb"),
                "numberField_lz85jlum":item.get("numberField_m0kodbta"),
                "textField_lz85phcm":form_data.get("textField_lz95zyrg"),
                "textField_lzm251h8":item.get("textField_m0kodbtc"),
                "textField_lzm251h7":item.get("textField_lzm251h7"),
                "numberField_lzm251ha":item.get("numberField_m0kodbtd"),
                "selectField_lzmcok0q":item.get("selectField_m0kodbte"),
                "textField_lzqey43d":form_data.get("selectField_m0kodbtg"),
            })
        except Exception as err:
            continue
    return ApiResponse.success("同步成功")


@csrf_exempt
@require_http_methods(["GET"])
def archive_frozen_account(request):
    form_uuid = report_form_uuid
    now_stamp = datetime.now().timestamp()
    param = [{"key":"dateField_m1in1ghn","value":int(now_stamp*1000),"type":"DOUBLE","operator":"lt","componentName":"DateField"}]
    result,total = yida_client.get_all_form_data_by_search_field(form_uuid,admin_user_id,param)
    person_ids = [item.form_data.get("selectField_lqwcqyd0_id") for item in result]
    for person_id in person_ids:
        try:
            yida_client.update_form_data_by_field("FORM-861F9E6F4AAE4D73A255247BF7991765XAKG",
                                                  admin_user_id,
                                                  [
                                                    {
                                                      "type": "TEXT",
                                                      "operator": "eq",
                                                      "componentName": "TextField",
                                                      "key": "textField_lp0zbal4",
                                                      "value": person_id
                                                    }
                                                  ],{
                                                      "selectField_lygntf4y":"冻结",
                                                      "textField_m204ou0w":"超过归档日期"
                                                  })
        except Exception as err:
            continue
    return ApiResponse.success("归档超时冻结成功")


@csrf_exempt
@require_http_methods(["GET"])
def auto_approve(request):
    form_inst_id = request.GET.get("form_inst_id")
    report_type = request.GET.get("report_type")
    area = request.GET.get("area")
    salsman = request.GET.get("salsman")
    threading.Thread(target=auto_approve_thread, args=(form_inst_id,report_type,salsman,area,)).start()
    return ApiResponse.success("自动受理任务已受理")

@csrf_exempt
@require_http_methods(["POST"])
def batch_process_agree(request):
    params = json.loads(request.body)
    remark = params.get("remark")
    userId = params.get("userId")
    taskInformationList = params.get("taskInformationList")
    try:
        yida_client.batch_process_agree(remark,userId,taskInformationList,"agree")
    except Exception as err:
        return ApiResponse.success("审批异常")
    return ApiResponse.success("批量同意已完成")


def auto_approve_thread(form_inst_id,report_type,salsman,area):
    time.sleep(10) # 延时等待宜搭进行到目标节点
    app_history = yida_client.get_approve_history(form_inst_id,admin_user_id)
    # target_node = next((item for item in reversed(app_history) if (item.action_exit == "doing")), None)
    target_node = next((item for item in reversed(app_history) if (item.show_name == "待审核" and item.action_exit == "doing")), None)
    if(target_node):
        result = yida_client.get_form_data_by_search_field("FORM-7F0A10A94E3D469882B2B1AA9700C1255JRO",
                                                  yida_client.admin_user_id,
                                                  [
                                                    {
                                                      "type": "TEXT",
                                                      "operator": "eq",
                                                      "componentName": "TextField",
                                                      "key": "textField_lpmab75n",
                                                      "value": report_type
                                                    }
                                                  ])
        form_data = result[0].form_data
        no_approve_salesman:str = form_data.get("textareaField_m3y31gn3") # 需要审核的业务员
        no_approve_area = form_data.get("tableField_m3y7zump") # 需要审核的地区
        no_approve_area_arr = ["_".join(item.get("cascadeSelectField_lpgahbwq_id")) for item in no_approve_area]
        if no_approve_salesman:
            no_approve_salesman_arr = no_approve_salesman.split("\n")
            if no_approve_salesman_arr and salsman in no_approve_salesman_arr:
                return
        if no_approve_area_arr and area in no_approve_area_arr:
            return
        yida_client.execute_task(form_inst_id,target_node.task_id,target_node.operator_user_id)

import oss2

@csrf_exempt
@require_http_methods(["GET"])
def archive_to_xujf_com(self):
    with open('yida_app_service/chengxiang/resorce/bak_list.txt', 'r') as file:
        records = file.readlines()

    # 去掉每行末尾的换行符，并返回一个列表
    records = [line.strip() for line in records]
    auth = oss2.Auth("LTAI5t6uQ1q8XbgYHwVBG7k9", "Q0bBMa76xxGEE2pC6US6ifYDUc5tX7")
    cname = 'https://doc.zjxmyq.cn'
    xm_bucket = oss2.Bucket(auth, cname, 'xiaming-report',
                        is_cname=True, connect_timeout=30)
    for index,record in enumerate(records):
        try:
            record_arr = record.split("	")
            report_id = record_arr[0]
            path = record_arr[1]
            logger.info(f"正在迁移第{index + 1}份报告: {record}")
            objects = xm_bucket.list_objects(prefix=path)
            for obj in objects.object_list:
                obj_key = obj.key
                download_url = xm_bucket.sign_url('GET', obj_key, 3600)
                with requests.get(download_url) as response:
                    logger.info("正在迁移...")
                    cover_content = response.content
                    bucket.put_object(obj_key, cover_content)
            logger.info("迁移完成")
            report = Report.objects.get(id=report_id)
            report.save()
        except Exception as err:
            logger.error(err)
    return ApiResponse.success("success")

@csrf_exempt
@require_http_methods(["GET"])
def transfer_to_xu_com(request):
    '''文件迁移'''
    skip_count = request.GET.get("skip_count",0)
    report_form_uuid = report_form_uuid
    file_path = "yida_app_service/chengxiang/resorce/bak_lists/0901_1101.xlsx"
    wb = openpyxl.load_workbook(file_path)
    ws = wb.active
    process_inst_ids = []
    for row in ws.iter_rows(min_row=2, max_col=1, values_only=True):
        process_inst_ids.append(row[0])
    for index,form_inst_id in enumerate(process_inst_ids):
        if index < int(skip_count):
            continue
        logger.info(f"正在迁移第{index + 1}份报告: {form_inst_id}")
        try:
            result = yida_client.get_form_items_by_ids(report_form_uuid,form_inst_id,admin_user_id)
            if result:
                start_backup_task_test(result[0],report_form_uuid)
            else:
                record_log(form_inst_id)
        except Exception as err:
            record_log(form_inst_id)
            logger.error(err)

@csrf_exempt
@require_http_methods(["POST"])
def batch_gen_report(request):
        req_data = json.loads(request.body)
        report_code_list = req_data.get("report_code_list")
        for report_code in report_code_list:
            regen = False
            try:
                report = Report.objects.get(report_code=report_code)
                if not report.digital_sign_order_no:
                    regen = True
            except Report.DoesNotExist:
                regen = True
            if regen:
                print(f"开始生成报告{report_code}")
                result = yida_client.get_form_data_by_search_field(report_form_uuid,admin_user_id,
                                                    [
                                                        {
                                                            "type": "TEXT",
                                                            "operator": "eq",
                                                            "componentName": "TextField",
                                                            "key": "textField_lp93kxup",
                                                            "value": report_code
                                                        }
                                                    ])
                model_uuid = result[0].form_data.get("textField_lqbsdaaj")
                form_inst_id = result[0].form_instance_id
                headers = {
                        'Content-Type': 'application/json'
                    }
                response = requests.post(f"https://api.zjcxjc.cn/api/v1/yida-app/chengxiang_2025/gen_base/{model_uuid}",
                              json={
                                  "formInstId": form_inst_id
                              },
                              headers=headers)
                if response.status_code == 200:
                    print("success")
                    with open("yida_app_service/chengxiang_2025/test_log.txt", "a", encoding="utf-8") as file:
                        file.write(f"{report_code}\n")
                    time.sleep(3)
                else:
                    print("error")
                    with open("yida_app_service/chengxiang_2025/test_err.txt", "a", encoding="utf-8") as file:
                        file.write(f"{report_code}\n")
                    time.sleep(3)
        return ApiResponse.success("生成报告任务已完成")